package com.navinfo.parkingnavi;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.pm.ActivityInfo;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;

import com.mapbox.android.core.location.LocationEngine;
import com.mapbox.android.core.location.LocationEngineCallback;
import com.mapbox.android.core.location.LocationEngineProvider;
import com.mapbox.android.core.location.LocationEngineRequest;
import com.mapbox.android.core.location.LocationEngineResult;
import com.mapbox.api.directions.v5.models.DirectionsRoute;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.location.LocationComponent;
import com.mapbox.mapboxsdk.location.LocationComponentActivationOptions;
import com.mapbox.mapboxsdk.location.modes.CameraMode;
import com.mapbox.mapboxsdk.location.modes.RenderMode;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.maps.Style;
import com.mapbox.services.android.navigation.ui.v5.ThemeSwitcher;
import com.mapbox.services.android.navigation.ui.v5.map.NavigationMapboxMap;
import com.mapbox.services.android.navigation.ui.v5.route.OnRouteSelectionChangeListener;
import com.navinf.parkingnavi.util.FragmentsManager;
import com.navinf.parkingnavi.util.MapManager;
import com.navinfo.parkingnavi.util.PositionUtil;

import pub.devrel.easypermissions.AfterPermissionGranted;
import pub.devrel.easypermissions.EasyPermissions;

/*
 *com.navinfo.parkingnavi
 *zhjch
 *2020/5/13
 *15:18
 *说明（）
 */
public abstract class MapActivity extends FragmentActivity
        implements MapboxMap.OnMapClickListener,
        MapboxMap.OnMapLongClickListener,
        LocationEngineCallback<LocationEngineResult>,
        OnRouteSelectionChangeListener, MapboxMap.OnCameraMoveListener {

    protected MapView mMapView;

    /**
     * fragment管理
     */
    protected FragmentsManager mFragmentsManager;
    /**
     * 地图管理
     */
    protected MapManager mMapManager;

    /**
     * 定位模块
     * Set up the LocationEngine and the parameters for querying the device's location
     */
    private LocationEngine locationEngine;


    // 导航所需地图，主要用来渲染导航路径
    protected NavigationMapboxMap navigationMapboxMap;
    protected ImageView img_main_navi;// 导航按钮

    @SuppressLint("SourceLockedOrientationActivity")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//强制竖屏
        setContentView(R.layout.activity_main);
        requirePermission();
        //初始化fragment管理
        mFragmentsManager = FragmentsManager.getInstance();
        mFragmentsManager.init(this);
        //初始画地图管理
        mMapManager = MapManager.getInstance();
        //初始化地图
        mMapView = findViewById(R.id.mapview);
        mMapView.onCreate(savedInstanceState);
        mMapView.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(@NonNull final MapboxMap mapboxMap) {
                mapboxMap.setStyle(new Style.Builder().fromUri("asset://v2x_style.json"), new Style.OnStyleLoaded() {
                    @Override
                    public void onStyleLoaded(@NonNull Style style) {
                        ThemeSwitcher.setTheme(MapActivity.this, null);
                        mapboxMap.addOnMapClickListener(MapActivity.this);
                        mapboxMap.addOnMapLongClickListener(MapActivity.this);
                        mapboxMap.addOnCameraMoveListener(MapActivity.this);
                        mapboxMap.getUiSettings().setCompassMargins(0, 150, 0, 0);

//                         初始化导航相关类
                        navigationMapboxMap = new NavigationMapboxMap(mMapView, mapboxMap, null);
                        navigationMapboxMap.setOnRouteSelectionChangeListener(MapActivity.this);
                        navigationMapboxMap.updateLocationLayerRenderMode(RenderMode.COMPASS);
                        mMapManager.init(MapActivity.this, mapboxMap, navigationMapboxMap, style);
                        enableLocationComponent(style);
                        styleLoaded();
                    }
                });
            }
        });
    }

    protected abstract void styleLoaded();
    /**
     * 开启定位，显示位置区域圆
     *
     * @param loadedMapStyle
     */
    private void enableLocationComponent(@NonNull Style loadedMapStyle) {

// Get an instance of the component
        LocationComponent locationComponent = MapManager.getInstance().getMapBox().getLocationComponent();
// Activate with options
        locationComponent.activateLocationComponent(
                LocationComponentActivationOptions.builder(this, loadedMapStyle)
                        .useDefaultLocationEngine(false).build());
// Enable to make component visible
        locationComponent.setLocationComponentEnabled(true);
// Set the component's camera mode
        locationComponent.setCameraMode(CameraMode.TRACKING);
// Set the component's render mode
        locationComponent.setRenderMode(RenderMode.COMPASS);
        initLocationEngine();
    }

    /**
     * 设置定位模式
     */
    @SuppressLint("MissingPermission")
    private void initLocationEngine() {
        locationEngine = LocationEngineProvider.getBestLocationEngine(this);

        LocationEngineRequest request = new LocationEngineRequest.Builder(1000L)
                .setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
                .setMaxWaitTime(5000L).build();

        locationEngine.requestLocationUpdates(request, this, getMainLooper());
    }

    /**
     * 获取权限
     */
    @AfterPermissionGranted(1)
    private void requirePermission() {
        String[] permissions = {
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.READ_PHONE_STATE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE
        };
        String[] permissionsForQ = {
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_BACKGROUND_LOCATION, //target为Q时，动态请求后台定位权限
                Manifest.permission.READ_PHONE_STATE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE
        };
        if (Build.VERSION.SDK_INT >= 29 ? EasyPermissions.hasPermissions(this, permissionsForQ) :
                EasyPermissions.hasPermissions(this, permissions)) {
            Toast.makeText(this, "权限OK", Toast.LENGTH_LONG).show();
        } else {
            EasyPermissions.requestPermissions(this, "需要权限",
                    1, Build.VERSION.SDK_INT >= 29 ? permissionsForQ : permissions);
        }
    }

    //处理权限
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (locationEngine != null) {
            locationEngine.removeLocationUpdates(this);
        }
        if (mFragmentsManager != null) {
            mFragmentsManager.onDestroy();
            mFragmentsManager = null;
        }
        if (mMapManager != null) {
            mMapManager.getMapBox().removeOnMapClickListener(this);
            mMapManager.onDestroy();
        }
        if (mMapView != null) {
            mMapView.onDestroy();
        }
    }

    @Override
    public void onBackPressed() {
        if (!mFragmentsManager.onBackPressed()) {
            System.exit(0);
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        if (mMapView != null) {
            mMapView.onStart();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mMapView != null) {
            mMapView.onResume();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mMapView != null) {
            mMapView.onPause();
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (mMapView != null) {
            mMapView.onStop();
        }
    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        if (mMapView != null) {
            mMapView.onSaveInstanceState(outState);
        }
    }


    @Override
    public void onLowMemory() {
        super.onLowMemory();
        if (mMapView != null) {
            mMapView.onLowMemory();
        }
    }

    @Override
    public boolean onMapClick(@NonNull LatLng point) {
        return true;
    }


    /**
     * 地图长点击事件处理
     */
    @Override
    public boolean onMapLongClick(@NonNull LatLng point) {
        return false;
    }


    /**
     * 用户选取其他导航路径
     */
    @Override
    public void onNewPrimaryRouteSelected(DirectionsRoute directionsRoute) {
    }
    boolean bFirst = true;
    //定位成功
    @Override
    public void onSuccess(LocationEngineResult result) {
        Location location = result.getLastLocation();

        if (location == null) {
            return;
        }
        //更新定位圆
        // Pass the new location to the Maps SDK's LocationComponent
        if (mMapManager.getMapBox() != null && result.getLastLocation() != null) {
            Location location1 = PositionUtil.gps84_To_Gcj02(location);
            mMapManager.getMapBox().getLocationComponent().forceLocationUpdate(location1);
        }
        if(bFirst) {
            CameraPosition cameraPosition = new CameraPosition.Builder()
                    .target(new LatLng(location.getLatitude(), location.getLongitude()))
                    .zoom(16)
                    .build();
            mMapManager.getMapBox().animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
            bFirst = false;
        }
    }

    //定位失败
    @Override
    public void onFailure(@NonNull Exception exception) {

    }

}
